package com.shujia.rec.service.impl;

import com.shujia.rec.dao.ContactDao;
import com.shujia.rec.domain.ContactEntity;
import com.shujia.rec.domain.ProduceAndScore;
import com.shujia.rec.service.RecommendService;
import com.shujia.rec.util.HbaseUtil;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HConnection;
import org.apache.hadoop.hbase.client.HTableInterface;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.util.Bytes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.*;

@Service
public class RecommendServiceImpl implements RecommendService {

    @Autowired
    private ContactDao ContactDao;

    @Override
    public List<ContactEntity> getRecList(String userId) {
        HConnection connection = HbaseUtil.getConnection();

        //用户购买历史，  用户评分向量
        ArrayList<ProduceAndScore> lists = new ArrayList<>();

        try {

            /**
             *
             * 1、获取用户历史购买列表
             *
             */
            HTableInterface u_history = connection.getTable("rec:u_history");
            Get get = new Get(userId.getBytes());
            Result result = u_history.get(get);
            List<Cell> cells = result.listCells();


            if (cells == null) {
                return new ArrayList<>();
            }

            for (Cell cell : result.listCells()) {
                String proId = Bytes.toString(CellUtil.cloneQualifier(cell));
                Double score = Double.parseDouble(Bytes.toString(CellUtil.cloneValue(cell)));
                ProduceAndScore produceAndScore = new ProduceAndScore(proId, score);
                lists.add(produceAndScore);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }


        /**
         * 计算推荐向量
         *
         */

        ArrayList<ProduceAndScore> topNList = new ArrayList<>();

        for (ProduceAndScore produceAndScore : lists) {
            String proId = produceAndScore.getProId();
            //用户评分
            Double score1 = produceAndScore.getScore();
            //获取当前商品相关联的所有商品
            try {
                HTableInterface table = connection.getTable("rec:similarity");

                Get get = new Get(proId.getBytes());
                Result result = table.get(get);
                List<Cell> cells = result.listCells();
                if (cells == null) {
                    return new ArrayList<>();
                }
                for (Cell cell : cells) {
                    String newProid = Bytes.toString(CellUtil.cloneQualifier(cell));
                    //相关性  商品相关性
                    double score = Double.parseDouble(Bytes.toString(CellUtil.cloneValue(cell)));

                    //加权评分
                    double v = score1 * score;

                    Boolean flag = true;

                    //只取用户没有购买过的商品
                    for (ProduceAndScore list : lists) {
                        if (list.getProId().equals(newProid)) {
                            flag = false;
                            break;
                        }
                    }
                    if (flag) {
                        topNList.add(new ProduceAndScore(newProid, v));
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


        //评分倒叙排序
        topNList.sort(new Comparator<ProduceAndScore>() {
            @Override
            public int compare(ProduceAndScore o1, ProduceAndScore o2) {
                if (o1.getScore() < o2.getScore()) {
                    return 1;
                } else {
                    return -1;
                }

            }
        });


        ArrayList<String> ids = new ArrayList<>();
        int top = 1;

      /*  if (topNList.size() < 10) {
            top = topNList.size();
        }*/

        //取topN
        for (int i = 0; i < top; i++) {
            ProduceAndScore produceAndScore = topNList.get(i);
            String proId = produceAndScore.getProId();
            ids.add(proId);
        }

        if (ids.isEmpty()) {
            return new ArrayList<>();
        }

        //获取商品信息
        List<ContactEntity> contactEntities = ContactDao.selectByIds(ids);


        HashMap<String, Double> topMap = new HashMap<>();
        for (ProduceAndScore produceAndScore : topNList) {
            topMap.put(produceAndScore.getProId(), produceAndScore.getScore());
        }


        for (ContactEntity contactEntity : contactEntities) {
            Double aDouble = topMap.get(Integer.toString(contactEntity.getId()));
            contactEntity.setScore(aDouble);
        }

        contactEntities.sort(new Comparator<ContactEntity>() {
            @Override
            public int compare(ContactEntity o1, ContactEntity o2) {
                if (o1.getScore() < o2.getScore()) {
                    return 1;
                } else {
                    return -1;
                }
            }
        });


        return contactEntities;
    }
}
